package felix.rule.api;


import felix.rule.data.msg.EngineMsg;
import felix.rule.data.msg.EngineMsgMetaData;
import felix.rule.js.script.ScriptEngine;
import felix.rule.js.util.ListeningExecutor;
import org.springframework.context.ApplicationContext;

import java.util.Set;

public interface TContext {

    /*
     *
     *  METHODS TO CONTROL THE MESSAGE FLOW
     *
     */

    /**
     * Indicates that message was successfully processed by the rule node.
     * Sends message to all Rule Nodes in the Rule Chain
     * that are connected to the current Rule Node using "Success" relationType.
     *
     * @param msg
     */
    void tellSuccess(EngineMsg msg);

    /**
     * Sends message to all Rule Nodes in the Rule Chain
     * that are connected to the current Rule Node using specified relationType.
     *
     * @param msg
     * @param relationType
     */
    void tellNext(EngineMsg msg, String relationType);

    /**
     * Sends message to all Rule Nodes in the Rule Chain
     * that are connected to the current Rule Node using one of specified relationTypes.
     *
     * @param msg
     * @param relationTypes
     */
    void tellNext(EngineMsg msg, Set<String> relationTypes);

    /**
     * Sends message to the current Rule Node with specified delay in milliseconds.
     * Note: this message is not queued and may be lost in case of a server restart.
     *
     * @param msg
     */
    void tellSelf(EngineMsg msg, long delayMs);

    /**
     * Notifies Rule Engine about failure to process current message.
     *
     * @param msg - message
     * @param th  - exception
     */
    void tellFailure(EngineMsg msg, Throwable th);

    void ack(EngineMsg engineMsg);

    EngineMsg newMsg(String queueName, String type, String originator, EngineMsgMetaData metaData, String data);

    EngineMsg transformMsg(EngineMsg origMsg, String type, String originator, EngineMsgMetaData metaData, String data);

    String getSelfId();

    String getRuleId();

    ScriptEngine createJsScriptEngine(String script);

    ListeningExecutor getJsExecutor();

    RuleChainTransactionService getRuleChainTransactionService();

    /**
     * 获取spring容器
     * @return
     */
    ApplicationContext getSpringContext();

}
